package com.kaili.common.util;

import com.sun.mail.util.MailSSLSocketFactory;
import java.io.File;
import java.util.*;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.*;

/**
 * 发送邮件
 * Created by linjian on 19-8-6.
 */
public class MailUtil {

    public static String sendAddress = "kaili@kaicom.cn";//企业邮箱
    public static String sendAccount = "kaili";//邮件签名
    public static String sendPassword = "wykaicom!@#";//企业邮箱(授权码)

    /**
     * 发送无附件的邮件(个人邮箱)
     * @param subject
     * @param content
     * @param emails
     * @return
     * @throws Exception
     */
    public static int sendEmail(String subject,String content,String emails) throws Exception {

        int result = 1;
        //连接邮箱服务器的参数设置
        Properties props = new Properties();
        //设置用户的认证方式
        props.setProperty("mail.smtp.auth","true");
        //设置传输协议
        props.setProperty("mail.transport.protocol","smtp");
        //设置发件人的SMTP服务器地址
        props.setProperty("mail.smtp.host","smtp.163.com");
        //创建定义session对象
        Session session = Session.getInstance(props);
        //可以在控制台打印出调试信息
        session.setDebug(true);
        //创建邮件实例对象
        Message msg = getMimeMessage1(session,subject,content,emails);
        //根据session对象获取邮件传输的对象
        Transport transport = session.getTransport();
        //设置发件人的账户名和密码(可以使用邮箱授权码)
        transport.connect(sendAccount,sendPassword);
        //发送邮件方法
        transport.sendMessage(msg,msg.getAllRecipients());
        //关闭资源
        transport.close();
        return result;
    }

    /**
     * 创建一封邮件实例对象(纯文本)
     * @param session
     * @param subject
     * @param content
     * @param emailAddress
     * @return
     * @throws Exception
     */
    private static Message getMimeMessage(Session session,String subject,String content,String emailAddress) throws Exception {
        //创建一封邮件的实例对象
        MimeMessage msg = new MimeMessage(session);
        //设置发件人地址
        msg.setFrom(new InternetAddress(sendAddress));
        //设置收件人地址(默认为抄送,即MimeMessage.RecipientType.CC)
        InternetAddress[] carbonCopy = InternetAddress.parse(emailAddress);
        msg.setRecipients(MimeMessage.RecipientType.CC, carbonCopy);
        //设置邮件主题
        msg.setSubject(subject,"utf-8");
        msg.setContent(content,"text/html;charset=UTF-8");
        msg.setSentDate(new Date());
        return msg;
    }

    /**
     * 创建一封邮件实例对象(带有图片,附件)
     * @param session
     * @param subject
     * @param content
     * @param emailAddress
     * @return
     * @throws Exception
     */
    private static Message getMimeMessage1(Session session,String subject,String content,String emailAddress) throws Exception {
        //创建一封邮件的实例对象
        MimeMessage msg = new MimeMessage(session);
        //设置发件人地址
        msg.setFrom(new InternetAddress(sendAddress));
        //设置收件人地址(默认为抄送,即MimeMessage.RecipientType.CC)
        InternetAddress[] carbonCopy = InternetAddress.parse(emailAddress);
        msg.setRecipients(MimeMessage.RecipientType.CC, carbonCopy);
        //设置邮件主题
        msg.setSubject(subject,"utf-8");

        //创建图片节点
        MimeBodyPart image = new MimeBodyPart();
        //读取图片路经
        DataHandler dh = new DataHandler(new FileDataSource(""));
        //添加到节点
        image.setDataHandler(dh);
        //为节点设置一个未已编号
        image.setContentID("mailTestPic");
        //创建文本节点
        MimeBodyPart text = new MimeBodyPart();
        //添加图片的方式将整个图片包含到邮件内容中
        text.setContent("这是一张测试图片<img src='cid:mailTestPic'>","text/html;charset=utf-8");
        //将文本+图片的content是由多个bodypart组成的multipart,所以学要的是bodyPart
        MimeMultipart mm_text_image = new MimeMultipart();
        mm_text_image.addBodyPart(text);
        mm_text_image.addBodyPart(image);
        mm_text_image.setSubType("related");//关联关系
        //上面的TestPic并非bodyPart,所以学封装成一个bodyPart
        MimeBodyPart text_image = new MimeBodyPart();
        text_image.setContent(mm_text_image);
        //创建附件节点
        MimeBodyPart arrachment = new MimeBodyPart();
        //读取文件路经
        DataHandler dh2 = new DataHandler(new FileDataSource(""));
        //将附件添加节点
        arrachment.setDataHandler(dh2);
        //设置附件的文件名(需要编码)
        arrachment.setFileName(MimeUtility.encodeText(dh2.getName()));

        //设置(文本+图片)和附件的关系
        MimeMultipart mm =new MimeMultipart();
        mm.addBodyPart(text_image);
        mm.addBodyPart(arrachment);
        mm.setSubType("mixed");

        msg.setContent(mm);
        msg.setSentDate(new Date());
        return msg;
    }

    /**
     * 创建一封邮件实例对象(可以上传多个附件)
     * @param session
     * @param mailObject 邮件信息
     * @param fileUrl 附件URL
     * @return
     * @throws Exception
     */
    public static Message mailMessage(Session session, HashMap<String,String> mailObject, List<File> fileUrl) throws Exception{
        String subject = mailObject.get("subject");//主题
        String content = mailObject.get("content");//正文
        String emailAddress = emailArrayParseString(mailObject.get("emailAddress"));//收件地址,

        MimeMessage msg = new MimeMessage(session);
        //设置发件人地址
        msg.setFrom(new InternetAddress(sendAddress));
        //设置收件人地址(默认为抄送,即MimeMessage.RecipientType.CC)
        InternetAddress[] carbonCopy = InternetAddress.parse(emailAddress);
        msg.setRecipients(MimeMessage.RecipientType.CC, carbonCopy);
        //设置邮件主题
        msg.setSubject(subject,"utf-8");

        //设置正文
        BodyPart bp = new MimeBodyPart();
        bp.setContent("<h1>"+content+"</h1>","text/html;charset=UTF-8");
        MimeMultipart mp = new MimeMultipart();
        mp.addBodyPart(bp);

        //设置附件
        if (null != fileUrl && fileUrl.size()>0){
            for (int i = 0; i < fileUrl.size(); i++) {
                bp=new MimeBodyPart();
                FileDataSource fds = new FileDataSource(fileUrl.get(i));
                bp.setDataHandler(new DataHandler(fds));
                bp.setFileName(MimeUtility.encodeText(fds.getName(),"UTF-8","B"));
                mp.addBodyPart(bp);
            }
        }
        msg.setContent(mp);
        msg.setSentDate(new Date());
        return msg;
    }

    /**
     * 创建一封邮件实例对象(不能上传附件)
     * @param session
     * @param mailObject 邮件信息
     * @return
     * @throws Exception
     */
    public static Message mailMessageNotFile(Session session, Map<String,String> mailObject) throws Exception{
        String subject = mailObject.get("subject");//主题
        String content = mailObject.get("content");//正文
        String emailAddress = emailArrayParseString(mailObject.get("emailAddress"));//收件地址,

        MimeMessage msg = new MimeMessage(session);
        //设置发件人地址
        msg.setFrom(new InternetAddress(sendAddress));
        //设置收件人地址(默认为抄送,即MimeMessage.RecipientType.CC)
        InternetAddress[] carbonCopy = InternetAddress.parse(emailAddress);
        msg.setRecipients(MimeMessage.RecipientType.CC, carbonCopy);
        //设置邮件主题
        msg.setSubject(subject,"utf-8");

        //设置正文
        BodyPart bp = new MimeBodyPart();
        bp.setContent("<h1>"+content+"</h1>","text/html;charset=UTF-8");
        MimeMultipart mp = new MimeMultipart();
        mp.addBodyPart(bp);

        msg.setContent(mp);
        msg.setSentDate(new Date());
        return msg;
    }

    public static String emailArrayParseString(String str){
        return str.replace(";",",");
    }

    /**
     * 校验邮箱地址是否正确
     * @param eamils
     * @return 0:超过10个邮箱;-1:格式错误;1:正确
     */
    public static Integer checkEmail(String eamils){

        //将输入带";"的地址串替换为","
        String emailAdress = eamils.replace(";",",");
        //将地址转为数组
        String[] arr =  emailAdress.split(",");
        //校验规则
        String regex = "\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*";
        if (arr.length>10){
            return 0;
        }else if (arr.length==1){
            //只有一个邮箱
            if (!eamils.matches(regex)){
                return -1;
            }
        }else{
            //多个邮箱
            for (String str : arr){
                if(!str.matches(regex)){
                    return -1;
                }
            }
        }
        return 1;
    }

    /***
     * 发送多个附件及多个抄送人的邮件(企业邮箱)
     * @param mailMap
     * @param file
     * @return
     * @throws Exception
     */
    public static int sendEmail(HashMap mailMap,List<File> file) throws Exception {

        //连接邮箱服务器的参数设置
        Properties props = new Properties();
        //设置用户的认证方式
        props.setProperty("mail.smtp.auth","true");
        //设置发件人的SMTP服务器地址
        props.setProperty("mail.smtp.host","smtp.ym.163.com");
        props.setProperty("mail.smtp.timeout","30000");//超时时间
        MailSSLSocketFactory sf = new MailSSLSocketFactory();

        sf.setTrustAllHosts(true);//设置信任所有主机
        props.put("mail.smtp.ssl.enable","true");
        props.put("mail.smtp.ssl.socketFactory",sf);

        //创建定义session对象
        Session session = Session.getInstance(props);
        //可以在控制台打印出调试信息
        session.setDebug(true);
        //创建邮件实例对象
        Message msg = mailMessage(session,mailMap,file);
        //根据session对象获取邮件传输的对象
        Transport transport = session.getTransport();
        //设置发件人的地址和密码(可以使用邮箱授权码)
        transport.connect(sendAddress,sendPassword);
        //发送邮件方法
        transport.sendMessage(msg,msg.getAllRecipients());
        //关闭资源
        transport.close();
        return 1;
    }

    /***
     * 发送多个抄送人的邮件(企业邮箱)
     * @param mailMap
     * @return
     * @throws Exception
     */
    public static int sendEmail(Map mailMap) throws Exception {

        //连接邮箱服务器的参数设置
        Properties props = new Properties();
        //设置用户的认证方式
        props.setProperty("mail.smtp.auth","true");
        //设置发件人的SMTP服务器地址
        props.setProperty("mail.smtp.host","smtp.ym.163.com");
        props.setProperty("mail.smtp.timeout","30000");//超时时间
        MailSSLSocketFactory sf = new MailSSLSocketFactory();

        sf.setTrustAllHosts(true);//设置信任所有主机
        props.put("mail.smtp.ssl.enable","true");
        props.put("mail.smtp.ssl.socketFactory",sf);

        //创建定义session对象
        Session session = Session.getInstance(props);
        //可以在控制台打印出调试信息
        session.setDebug(true);
        //创建邮件实例对象
        Message msg = mailMessageNotFile(session,mailMap);
        //根据session对象获取邮件传输的对象
        Transport transport = session.getTransport();
        //设置发件人的地址和密码(可以使用邮箱授权码)
        transport.connect(sendAddress,sendPassword);
        //发送邮件方法
        transport.sendMessage(msg,msg.getAllRecipients());
        //关闭资源
        transport.close();
        return 1;
    }

}
